'use client';

import { type ChangeEvent, type FormEvent, useEffect, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import {
  createContact,
  removeContact,
  updateUserPersonalityInfo,
} from '@/services/api';
import type { IContact, IDifference, IUser } from '@/interfaces';
import diff from 'microdiff';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import Nodata from '@/app/[locale]/common/nodata/nodata';

export default function UpdateUserPersonality(
  this: any,
  {
    source,
    translatedFields,
  }: {
    source: IUser;
    translatedFields: PrefixedTTranslatedFields<'userAdminPage'>;
  },
) {
  const [form, setForm] = useState<{
    personalizedSignature?: string;
    smallAvatarUrl?: string;
    mediumAvatarUrl?: string;
    largeAvatarUrl?: string;
    contacts?: {
      id: string;
      key: string;
      val: string;
    }[];
    about?: string;
  }>({
    personalizedSignature: source.details!.personalizedSignature ?? '',
    smallAvatarUrl: source.details!.smallAvatarUrl ?? '',
    mediumAvatarUrl: source.details!.mediumAvatarUrl ?? '',
    largeAvatarUrl: source.details!.largeAvatarUrl ?? '',
    contacts: source.details!.contacts ?? [],
    about: source.details!.about ?? '',
  });
  const [contact, setContact] = useState<{
    key: string;
    val: string;
  }>({
    key: '',
    val: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const { show } = useToast();
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const updateUserPersonalityInfoMutation = useMutation(
    updateUserPersonalityInfo,
  );
  const createContactMutation = useMutation(createContact);
  const removeContactMutation = useMutation(removeContact);

  useEffect(() => {
    const diffData = diff(
      {
        personalizedSignature: source.details!.personalizedSignature ?? '',
        smallAvatarUrl: source.details!.smallAvatarUrl ?? '',
        mediumAvatarUrl: source.details!.mediumAvatarUrl ?? '',
        largeAvatarUrl: source.details!.largeAvatarUrl ?? '',
        contacts: source.details!.contacts ?? [],
        about: source.details!.about ?? '',
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, source]);

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      const data = getDiffData(differenceData);
      const id = source.id;
      await updateUserPersonalityInfoMutation.mutateAsync({
        id,
        data,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      updateUserPersonalityInfoMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
    }
  }

  async function onClickCreateContact() {
    try {
      if (!contact.key || !contact.val) {
        show({
          type: 'DANGER',
          message: translatedFields.tip.contactsRequired,
        });
        return;
      }

      const id = source.id;
      await createContactMutation.mutateAsync({
        id: source.id,
        data: contact,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      createContactMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  async function onClickRemoveContact(item: IContact) {
    try {
      const id = source.id;
      const contactId = item.id;
      await removeContactMutation.mutateAsync({
        id,
        data: {
          contactId,
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.deleteCompleted,
      });
    } catch (e) {
      removeContactMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onChangeForm(
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;
    setForm({ ...form, [name]: value });
  }

  function onChangeContact(e: ChangeEvent<HTMLInputElement>) {
    const name = e.target.name;
    const value = e.target.value.trim();

    if (name === 'contact-name') {
      setContact({ ...contact, key: value });
    } else if (name === 'contact-content') {
      setContact({ ...contact, val: value });
    }
  }

  return (
    <Box>
      <form onSubmit={onClickSave} className="vstack gap-4">
        <div>
          <label className="form-label">
            {translatedFields.properties.personalizedSignature}
          </label>
          <input
            type="text"
            className="form-control"
            name="personalizedSignature"
            value={form.personalizedSignature}
            onChange={onChangeForm}
            aria-describedby="personalizedSignature"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.properties.smallAvatarUrl}
          </label>
          <input
            type="text"
            className="form-control"
            name="smallAvatarUrl"
            value={form.smallAvatarUrl}
            onChange={onChangeForm}
            aria-describedby="smallAvatarUrl"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.properties.mediumAvatarUrl}
          </label>
          <input
            type="text"
            className="form-control"
            name="mediumAvatarUrl"
            value={form.mediumAvatarUrl}
            onChange={onChangeForm}
            aria-describedby="mediumAvatarUrl"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.properties.largeAvatarUrl}
          </label>
          <input
            type="text"
            className="form-control"
            name="largeAvatarUrl"
            value={form.largeAvatarUrl}
            onChange={onChangeForm}
            aria-describedby="largeAvatarUrl"
          />
        </div>

        <div>
          <label className="form-label">
            {translatedFields.properties.contacts}
          </label>

          <div>
            {(form.contacts || []).length > 0 && (
              <div className="table-responsive">
                <table className="table table-hover table-bordered align-middle">
                  <thead>
                    <tr className="text-nowrap">
                      <th scope="col" className="w-10 fw-normal">
                        {translatedFields.properties.name}
                      </th>
                      <th scope="col" className="w-10 fw-normal">
                        {translatedFields.properties.content}
                      </th>
                      <th scope="col" className="w-10"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {(source.details!.contacts || []).map((item) => {
                      return (
                        <tr key={item.id} className="text-nowrap">
                          <td>{item.key}</td>
                          <td>{item.val}</td>
                          <td>
                            <button
                              disabled={removeContactMutation.isLoading}
                              onClick={onClickRemoveContact.bind(this, item)}
                              className="btn btn-sm btn-danger"
                              type="button"
                            >
                              {removeContactMutation.isLoading ? (
                                <Spinner classs="me-2" />
                              ) : (
                                <i className="bi bi-trash me-2"></i>
                              )}
                              {translatedFields.operate.delete}
                            </button>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}

            {(form.contacts || []).length === 0 && <Nodata />}
          </div>

          <div className="input-group mt-4">
            <input
              type="text"
              className="form-control"
              value={contact.key}
              name="contact-name"
              aria-label="contact-name"
              onChange={onChangeContact}
            />
            <input
              type="text"
              className="form-control"
              value={contact.val}
              name="contact-content"
              aria-label="contact-content"
              onChange={onChangeContact}
            />
            <button
              disabled={createContactMutation.isLoading}
              onClick={onClickCreateContact}
              className="btn btn-outline-primary"
              type="button"
            >
              {createContactMutation.isLoading ? (
                <Spinner classs="me-2" />
              ) : (
                <i className="bi bi-plus-lg me-2"></i>
              )}
              {translatedFields.operate.add}
            </button>
          </div>
        </div>

        <div>
          <label className="form-label">
            {translatedFields.properties.about}
          </label>
          <textarea
            rows={3}
            className="form-control"
            name="about"
            value={form.about}
            onChange={onChangeForm}
            aria-describedby="about"
          />
        </div>

        <button
          type="submit"
          disabled={
            updateUserPersonalityInfoMutation.isLoading || isDisabledSave
          }
          className="btn btn-success col col-lg-2 my-4"
        >
          {updateUserPersonalityInfoMutation.isLoading && (
            <Spinner classs="me-2" />
          )}
          {translatedFields.operate.update}
        </button>
      </form>
    </Box>
  );
}
